担当者無しチケットへの自動定期アサインにて棚卸しの効率化を図ってみた

担当者無しチケットへの自動定期アサインにて棚卸しの効率化を図ってみた

未完了なBackLogチケットのうち、未着手・担当者不在のケースについて進捗を促すために担当者自動アサイン用スクリプトで対処を試みました。
Clock Icon2024.05.29

先日、長く停留していたチケットの棚卸し記事を書きましたが、比較的片付けやすいチケットでした。

チケット一覧上から一目で進捗が察せれない状況もあります。例えば、未着手にて担当者が空になっているケース。誰も触っていないものと判断しそうですが、実は以下のような状況になっていたりします。

  • 作業は行われていないが、コメントにて開発室持ちとして今後の進展含めて相談されているもの
  • 何らかの実作業に入っているもののチケットが更新されていないもの

「一つ一つのチケットを開いて確認すれば分かる」と声も上がりそうですが、そのようなチケットが数増えてくると確認だけで大きく時間を取られる状況にもなりかねません。

全てのチケットに負荷少なめに適切な対処を取りたいものの、汎用的な手順は取りづらい。かといって放置すると未完了チケットは増えていくばかり。取っ掛かりとして、まずは設定漏れ等の対処が必要なチケットに対して最低限のステータス更新を起こすことにしました。

今回対象とするチケット

以下3点を満たすものとしました。

  • 前日に作成
  • ステータスが未着手
  • 担当者が空

コメントもなしと縛りたいところですが、参考資料のファイルをコメントにて添付されているケースが見当たったため外しました。

サービス開発室では指名の手間を減らす目的で汎用のチケット受付用アサインユーザを用意しており、依頼者がチケット発行時に受付用アサインユーザを担当者として設定する手続きとしています。

ですが、手続き漏れにて担当者設定のないケースもあります。この場合、持ちが依頼者か開発室なのか判りづらくなり、結果放置される可能性があります。そこで、担当者を自動で補完することにより本来想定する状況に移して、進捗を上げやすくします。

手順としては、定期的にGASで対象チケットを取得し、担当者欄をアップデートします。課題追加をトリガーとするwebhookにて自動設定する手もありますが、webhook対象となるアクセスポイントを常設するコストとGASで定期的に纏めて担当者を設定するコストを比較すると、後者のほうが比較的に安くつきます。

担当者更新用スクリプト

// 未着手で担当者も空になっているチケットを、担当者:サービス開発室 に更新する
function AssignBacklogTickets() {
    var prop = PropertiesService.getScriptProperties();
    var apiKey = prop.getProperty('BACKLOG_API_KEY');
    var spaceId = prop.getProperty('BACKLOG_SPACE_ID');
    var projectId = prop.getProperty('PROJECT_ID');
    var BACKLOG_ISSUE_ENDPOINT = "https://" + spaceId + ".backlog.jp/api/v2/issues";
    var BACKLOG_VIEW_URL = "https://" + spaceId + ".backlog.jp/view";
    var d = new Date();
    var n = new Date(d.getFullYear(), d.getMonth(), d.getDate() - 1, 0,0,0)
    var since = Utilities.formatDate(n, 'JST', 'yyyy-MM-dd');
    Logger.log(since)
    var res = UrlFetchApp.fetch(BACKLOG_ISSUE_ENDPOINT + "?apiKey=" + apiKey + "&projectId[]=" + projectId + "&statusId[]=1&createdSince=" + since);
    var contents = JSON.parse(res.getContentText());
    if (contents.length == 0) return

    for (var i=0;i < contents.length;i++) {
      if (contents[i].assignee != null) continue
      var fetchUrl = BACKLOG_ISSUE_ENDPOINT + "/" + contents[i].issueKey + "?apiKey=" + apiKey
      var result = UrlFetchApp.fetch(fetchUrl, {
        'method': 'PATCH',
        'contentType':' application/x-www-form-urlencoded',
        'payload': {
          'assigneeId': '00000000000'
        },
        'muteHttpExceptions': true
      })
      Logger.log(result)
    }
}

assigneeIdに対して受付用ユーザIDの自動アサインを目標としました。ユーザIDはBackLogのブラウザメニュー上では確認できず、APIで確認する必要があります。APIを実行するユーザでAPI Keyを発行し、エンドポイントapi/v2/users/myselfにアクセスします。

curl 'https://XX.backlog.jp/api/v2/users/myself?apiKey=XXXXXXXXXXXXXXXXXXXXXXXX' | jq
{
  id: 0000000000,
  userId: "[email protected]",
  name: "サービス開発室",
  roleType: 0,
  lang: "ja",
  mailAddress: "[email protected]",
  nulabAccount: {
    nulabId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    name: "サービス開発室",
    uniqueId: "xxxxxxxxx",
    iconUrl: "https://apps.nulab.com/account/xxxxxxxxxx/photo/large?t=00000000"
  },
  keyword: "サービス開発室 SA-BISUKAIHATUSHITU",
  lastLoginTime: "2023-01-01T00:00:00Z"
}

idがassigneeIdに指定すべき数値となります。idを即コピーしたい場合は以下のコマンドでもよいでしょう。

curl 'https://XX.backlog.jp/api/v2/users/myself?apiKey=XXXXXXXXXXXXXXXXXXXXXXXX' | jq '.id' | pbcopy

更新のタイミング

1日に1度としています。一定時間毎に実行すると常に漏れなくなりますが、GASのトリガーは実行時毎に1つ必要で、勤務時間中満遍なく設定すると相応数のトリガーになり、メンテナンスの手間が増えることを意味します。週1回の定期棚卸し迄に着手されれば良しとしました。

実際の動作

チケット次第ですが、依頼者が担当者未設定のままチケットの不明点を追記する最中で放置となっていた場合、自動で開発室預かりになることで、不明な点を依頼者にヒアリングするという流れを想定しています。

作業が進んでいて実は依頼者による確認中だった場合は、開発室スタッフがチケットを確認次第ステータスを処理中にして担当者を依頼者に切り替え等、現状に合わせることになるでしょう。元が未着手ステータスで担当者も空の状態であるため、作業に対して設定もれがあったと判ります。

実態に沿わない担当者のアップデートは問題があるように見えますが、受付用アサインユーザは棚卸し等の自動処理を特定スタッフに依存させずに行うことを目的としています。受付用アサインユーザによる処理が実行される時点で、何らかの理由で処置対象となったと見做される想定です。

また、担当者の設定だけに留めており、ステータスは変更していないのがポイントです。確認していないのに進んでいる状態にすることは作業進捗に誤認を発生させます。

あとがき

棚卸しし辛い状況にあるチケットのうち、設定不足にて動いているのか分からないチケットを進ませることに着目してみました。

ステータスが未着手であれば全てリマインドしても良さそうに見えますが、開発室持ちとなっている場合は直接の作業は発生せずとも何らかの対応が走っているケースが殆どでした。担当者が空の場合、持ちが開発室側か依頼者側か判りづらいため定期棚卸しでも着手のお見合いが発生しかねず、一旦強制で開発室持ちにすることで合理的な解消への働きかけとしています。

チケットに対する考え方にもよりますが、一例として参考になれば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.